﻿@using System.Security.Claims;
@using BlazorBlogs.Data;
@using BlazorBlogs.Data.Models;
@using Microsoft.AspNetCore.Hosting;
@using Microsoft.EntityFrameworkCore;
@inject IConfiguration _configuration
@inject GeneralSettingsService _GeneralSettingsService
@inject BlogsService _BlogsService
@inject IWebHostEnvironment _IWebHostEnvironment
@inject NavigationManager NavigationManager
@inherits OwningComponentBase

@if (@ErrorMessage != "")
{
    <h4>@ErrorMessage</h4>
}
else
{
    <h4>@ExecuteScriptsMode...</h4>
    <RadzenProgressBar Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate" Style="margin-bottom: 20px" />
}

@code {
    [CascadingParameter]
    private Task<AuthenticationState> authenticationStateTask { get; set; }

    // ExecuteScriptsChanged is an EventCallback that will
    // notify the parent component ExecuteScripts Is complete
    [Parameter] public EventCallback<bool> ExecuteScriptsChanged { get; set; }

    [Parameter] public string ExecuteScriptsMode { get; set; }

    int intCurrentDatabaseVersion = 0;
    string ErrorMessage = "";
    string VersionNumber = "";

    ClaimsPrincipal CurrentUser = new ClaimsPrincipal();

    protected override async Task OnInitializedAsync()
    {
        // Get current user
        CurrentUser = (await authenticationStateTask).User;

        _GeneralSettingsService = (GeneralSettingsService)ScopedServices.GetService(typeof(GeneralSettingsService));
        _BlogsService = (BlogsService)ScopedServices.GetService(typeof(BlogsService));

        // Get the version Number
        try
        {
            var GeneralSettings = await _GeneralSettingsService.GetGeneralSettingsAsync();
            VersionNumber = GeneralSettings.VersionNumber;
        }
        catch
        {
            VersionNumber = "00.00.00";
        }

        intCurrentDatabaseVersion = ConvertVersionToInteger(VersionNumber);
    }

    protected override async Task
        OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            StateHasChanged();
            Task.Delay(1000).Wait();

            // Get database conection string
            string strDefaultConnection = _configuration["ConnectionStrings:DefaultConnection"];

            // Get the scripts
            Dictionary<int, string> ColScripts = UpdateScripts();
            foreach (var sqlScript in ColScripts)
            {
                try
                {
                    // Only run the script if it is higher than the
                    // current database version
                    if (sqlScript.Key > intCurrentDatabaseVersion)
                    {
                        string strSQLScript = GetSQLScript(sqlScript.Value);

                        var optionsBuilder = new DbContextOptionsBuilder<BlazorBlogsContext>();
                        optionsBuilder.UseSqlServer(strDefaultConnection);

                        using (var context = new BlazorBlogsContext(optionsBuilder.Options))
                        {
                            try
                            {
                                await context.Database.ExecuteSqlRawAsync(strSQLScript);
                            }
                            catch (Exception ex)
                            {
                                ErrorMessage = ex.Message;
                                StateHasChanged();
                                return;
                            }

                            Task.Delay(1000).Wait();
                        }
                    }
                }
                catch (Exception ex)
                {
                    ErrorMessage = ex.Message;
                    StateHasChanged();
                    return;
                }
            }

            // Notify parent component
            await ExecuteScriptsChanged.InvokeAsync(true);
        }
    }

    #region private static int ConvertVersionToInteger(string strParamVersion)
    private static int ConvertVersionToInteger(string strParamVersion)
    {
        int intVersionNumber = 0;

        if (strParamVersion != "")
        {
            // Strip out possible .sql in string
            string strVersion = strParamVersion.Replace(".sql", "");

            // Split into parts seperated by periods
            char[] splitchar = { '.' };
            var strSegments = strVersion.Split(splitchar);

            // Process the segments
            int i = 0;
            List<int> colMultiplyers = new List<int> { 10000, 100, 1 };
            foreach (var strSegment in strSegments)
            {
                int intSegmentNumber = Convert.ToInt32(strSegment);
                intVersionNumber = intVersionNumber + (intSegmentNumber * colMultiplyers[i]);
                i++;
            }
        }

        return intVersionNumber;
    }
    #endregion

    #region private String GetSQLScript(string SQLScript)
    private String GetSQLScript(string SQLScript)
    {
        string strSQLScript = "";
        string strFilePath = _IWebHostEnvironment.ContentRootPath + $@"\SQLScripts\{SQLScript}";

        strSQLScript = System.IO.File.ReadAllText(@strFilePath);

        return strSQLScript;
    }
    #endregion

    private static Dictionary<int, string> UpdateScripts()
    {
        Dictionary<int, string> ColScripts = new Dictionary<int, string>();

        ColScripts.Add(ConvertVersionToInteger("00.10.00.sql"), "00.10.00.sql");
        ColScripts.Add(ConvertVersionToInteger("00.20.00.sql"), "00.20.00.sql");
        ColScripts.Add(ConvertVersionToInteger("01.00.00.sql"), "01.00.00.sql");
        ColScripts.Add(ConvertVersionToInteger("01.00.20.sql"), "01.00.20.sql");
        ColScripts.Add(ConvertVersionToInteger("01.00.30.sql"), "01.00.30.sql");
        ColScripts.Add(ConvertVersionToInteger("01.00.40.sql"), "01.00.40.sql");
        ColScripts.Add(ConvertVersionToInteger("01.00.50.sql"), "01.00.50.sql");
        ColScripts.Add(ConvertVersionToInteger("01.00.60.sql"), "01.00.60.sql");
        ColScripts.Add(ConvertVersionToInteger("01.00.70.sql"), "01.00.70.sql");
        ColScripts.Add(ConvertVersionToInteger("01.00.80.sql"), "01.00.80.sql");
        ColScripts.Add(ConvertVersionToInteger("01.00.90.sql"), "01.00.90.sql");
        ColScripts.Add(ConvertVersionToInteger("01.01.00.sql"), "01.01.00.sql");
        ColScripts.Add(ConvertVersionToInteger("01.01.10.sql"), "01.01.10.sql");
        ColScripts.Add(ConvertVersionToInteger("02.00.00.sql"), "02.00.00.sql");

        return ColScripts;
    }
}
